﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Media;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HotCopperUserScanService;
using System.Linq;
using System.Diagnostics;

namespace ScanFormsUI
{
    public partial class Scanner : Form
    {
        private PostsTimer _postsTimer;
        private SoundPlayer _soundPlayer;
        private SoundPlayer _errorsSoundPlayer;
        private string[] _editableColumns = { "Code", "FirstPrice", "Target" };

        public delegate void RefreshGridEventHandler();

        public Scanner()
        {
            InitializeComponent();
        }

        private void Scanner_Load(object sender, EventArgs e)
        {
            _soundPlayer = new SoundPlayer("push.wav");
            _errorsSoundPlayer = new SoundPlayer("error.wav");
 
            StartPostsTimer();

            postsGrid.AutoGenerateColumns = false;
            postsGrid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
            postsGrid.DataSource = _postsTimer.PostsDisplay;
            
            SetupPostsGrid();
            postsGrid.EditMode = DataGridViewEditMode.EditOnKeystroke;
            postsGrid.ReadOnly = false;
        }

        private void SetupPostsGrid()
        {

            postsGrid.Columns.AddRange(new DataGridViewColumn[] 
            {
                new DataGridViewTextBoxColumn() { HeaderText = "Date & Time", Name = "DateTime", Width = 150, DataPropertyName = "DateTime", ReadOnly = true },
                new DataGridViewTextBoxColumn() { 
                    HeaderText = "Message", Name = "Content", Width = 450, DataPropertyName = "Content", ReadOnly = true,
                    DefaultCellStyle = new DataGridViewCellStyle() { WrapMode = DataGridViewTriState.True}},
                new DataGridViewTextBoxColumn() { HeaderText = "User", Name = "Username", Width = 150, DataPropertyName = "Username", ReadOnly = true },
                new DataGridViewTextBoxColumn() { HeaderText = "Code", Name = "Code", Width = 100, DataPropertyName = "Code", ReadOnly = false },
                new DataGridViewTextBoxColumn() { HeaderText = "1st Price", Name = "FirstPrice", Width = 100, DataPropertyName = "FirstPrice", ReadOnly = false },
                new DataGridViewTextBoxColumn() { HeaderText = "Target", Name = "Target", Width = 100, DataPropertyName = "Target", ReadOnly = false },
                new DataGridViewLinkColumn() { HeaderText = "Link", Name = "Uri", Width = 450, DataPropertyName = "Uri", ReadOnly = true }
            }
            );
       
        }

        private void StartPostsTimer()
        {
            _postsTimer = new PostsTimer(new HotCopperBrowser());
            _postsTimer.NewPostsEvent += PostsTimerOnNewPostsEvent;
            _postsTimer.NewErrorsEvent += PostsTimerOnNewErrorsEvent;
            _postsTimer.Start();
        }

        private void PostsTimerOnNewErrorsEvent(object sender, ICollection<string> newErrors)
        {
            this.BeginInvoke(UpdateErrorsGrid());
        }

        private void PostsTimerOnNewPostsEvent(object sender, List<Post> newPosts)
        {
            this.BeginInvoke(UpdateGrid(newPosts));
            SendEmail(newPosts);
        }

        private void SendEmail(IList<Post> newPosts)
        {
            try
            {
                var sendEmail = new SendPostsEmail();
                var body = new StringBuilder();
                foreach (var post in newPosts)
                {
                    body.AppendLine(post.DateTime.ToString());
                    body.AppendLine(post.Username);
                    body.AppendLine(post.Content);
                }
                sendEmail.SendEmail("nzdunic@iinet.net.au", new string[] { "n_zdunic@yahoo.com.au", "nick@aboutagile.com" }, "Hotcopper Scanner New Posts", body.ToString());
            }
            catch (Exception ex)
            {
                this.BeginInvoke(UpdateEmailErrorsGrid(ex));
            }
        }

        private Delegate UpdateEmailErrorsGrid(Exception ex)
        {
            return new RefreshGridEventHandler(() =>
            {
                emailErrorsGrid.Rows.Add(string.Format("Error occured at {0}, with message {1}", DateTime.Now, ex.Message));
                _errorsSoundPlayer.Play();
            });
        }

        private Delegate UpdateGrid(List<Post> newPosts)
        {
            return new RefreshGridEventHandler(() =>
            {

                foreach (var post in newPosts.OrderBy(p => p.DateTime))
                {
                    _postsTimer.PostsDisplay.Insert(0, post);
                }

                postsGrid.DataSource = null;
                postsGrid.DataSource = _postsTimer.PostsDisplay;
                postsGrid.Update();
                postsGrid.Refresh();

                _soundPlayer.Play();
            });
        }

        private Delegate UpdateErrorsGrid()
        {
            return new RefreshGridEventHandler(() =>
            {

                errorsGrid.DataSource = null;

                errorsGrid.DataSource = _postsTimer.Errors.ToList().ConvertAll(x => new { Value = x });
                errorsGrid.Update();
                errorsGrid.Refresh();

                _errorsSoundPlayer.Play();
            });
        }

        private void Scanner_FormClosing(object sender, FormClosingEventArgs e)
        {
            _postsTimer.Stop();
        }

        private void postsGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == postsGrid.Columns["Uri"].Index)
            {
                Process.Start(postsGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value as string);
            }
        }

        private void SaveButton_Click(object sender, EventArgs e)
        {
            PostsDatabase.Update(_postsTimer.PostsDisplay);
        }

        //private void postsGrid_CellEnter(object sender, DataGridViewCellEventArgs e)
        //{
        //    return;
        //    if (_editableColumns.Contains(postsGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].OwningColumn.Name))  
        //    {
        //        postsGrid.CurrentCell = postsGrid.Rows[e.RowIndex].Cells[e.ColumnIndex];
        //        postsGrid.BeginEdit(true);
        //    }
        //}


    }
}
